home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
batchut
/
batutl2.zip
/
ASK.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-04-19
|
10KB
|
351 lines
; ASK program to enable you to ask questions and let users type in a
; one-character response. This allows you to build simple menu-driven
; batch file or yes/no type questions.
;
; See the external docuementation for more details.
; Written by Peter Wu; April, 1986
; UUCP: {seismo|ihnp4|harvard|ucbvax|allegra|topaz}!uwvax!uwmacc!pwu
; ARPA: pwu@unix.macc.uwisc.edu
;
; Slightly tweaked by David Kirschbaum, Toad Hall
ARGL equ 80h ; start of command line
SPECIAL equ '^' ; the special escape character
SWITCH equ '/' ; switch character preceeding options
CMDLEN equ 150 ; max length of converted cmd line
MAXARGC equ 4 ; max # of arguements
SQUOTE equ 39 ; ASCII of '
CR equ 0DH
LF equ 0AH
All SEGMENT 'CODE'
ASSUME CS:All,DS:All
ORG 100h
Entry proc near
jmp Start
;********************** data area ***********************
line db CMDLEN dup(?) ; store the converted command line
argc db ?
argv dw MAXARGC * 2 dup(?) ; *argv[]
option db 1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1
; a b c d e f g h i j k l m n o p q r s t u v w x y z
; 0 = option off, 1=invalid option, 2 = option on
cry db 'unknown option ',SQUOTE
unkopt db ? ; fill in the unknown option here
db SQUOTE,' ignored',CR,LF,'$'
;*********************** code area **********************
; GetC returns a converted character. bx should point to command line
; cl should contain the length of the command line
; ah=0 if normal character; ah='\' if special character.
three db ? ; for counting down from 3
ten db 10 ; for multiplying
Entry endp
GetC proc near
xor ax,ax ; clear character
sub cl,1 ; len = len - 1
jc Eoln ; reached end of command line
mov al,[bx] ; get a character
inc bx ; point to next one
cmp al,SPECIAL ; is it the special char '\' ?
jnz Normal ; nop; just a normal character
sub cl,1 ; len = len - 1
jc Eoln ; last character is '\'; ignore it
mov ah,al ; flag special char
mov al,[bx] ; get the next char
inc bx ; point to next char
; translate \nnn characters into ascii
cmp al,'0' ; see if first n is a digit
jb NotDig ; not a digit
cmp al,'9'
ja NotDig ; not a digit
; first n is a digit
xor ch,ch ; init accumulator
mov three,3 ; convert 3 digits at most
Digit: sub al,'0' ; convert to binary
; now multiply cl by ten and add al to it
xchg al,ch ; do this so we can use al to multiply
mul ten ; assume result is still 8 bits
add ch,al ; one digit is done.
; more digits?
dec three
jz GotIt ; converted all three digits
mov al,[bx] ; examine next char
cmp al,'0' ; is it a digit
jb GotIt ; not a digit; end translation
cmp al,'9'
ja GotIt ; not a digit; end translation
inc bx ; point to next char
jmp Digit ; process digit
GotIt: mov ah,SPECIAL ; flag special char even for \nnn
mov al,ch ; return char in al
Normal: ret
NotDig: ; not \nnn (e.g. \a \b \c \d ...)
cmp al,SPECIAL ; \\ => \
je Skip
cmp al,'"' ; \" => "
je Skip
and al,31 ; \a => ctrl-a; \b => ctrl-b; ...
Skip: ret
Eoln: xor ax,ax ; return end-of-line char
ret
GetC endp
;*********************** PrtS **********************
count dw ?
p dw ?
PrtS proc near ; print string to stdout; si points to string
mov ax,[si+2] ; pointer to string
mov p,ax ; save pointer
mov ax,[si] ; get length of string
mov count,ax
Ploop: sub count,1
jc D1 ; end of string
mov bx,p
mov dl,[bx] ; current character to be printed
inc p ; point to next character
mov ah,2 ; function number for print character
int 21h ; print character
jmp Ploop ; repeat
D1: ret
PrtS endp
;********************* main *********************
mc db ? ; loop index
char db ? ; key pressed by user
crlf db CR,LF,'$' ; crlf string
helpms db 'Usage:',CR,LF
db ' ask [',SWITCH,'c',SWITCH,'q] '
db '"prompt message" "expected response"',CR,LF,LF
db ' ',SWITCH,'c makes the response case sensitive',CR,LF
db ' ',SWITCH,'q will accept non-expected response (returns 0)',CR,LF
db ' "prompt message" and "expected response" are quoted strings',CR,LF
db ' To embed special characters use ',SPECIAL
db 'nnn where nnn is a 3-digit ASCII',CR,LF
db ' or ',SPECIAL,'a for ctrl-a, ',SPECIAL,'b for'
db ' ctrl-b, ... (except ',SPECIAL,SPECIAL,' for ',SPECIAL,' itself',CR,LF
db ' and ^" for the quote character)',CR,LF
db ' Response can be tested with if errorlevel',CR,LF
db ' Errorlevel is set to index("expected response",key pressed)',CR,LF,LF
db 'See the external document for more information',CR,LF
db '$'
nom db '*BEEP* Unexpected response',CR,LF,LF,'$'
Start proc near
mov bx,ARGL ; start of parameters
mov cl,[bx] ; length of parameter
inc bx ; now point to first char
mov di,offset line ; point to convert line buffer
mov si,offset argv - 4 ; point to *argv[0] - 4
mov argc,0 ; normally start at 1; but for ask.com 0 is ok
; now split command line into arguements in argv[]
Loopit:
cmp argc,MAXARGC ; can we handle more arguements?
jae Done ; if not; get out
call GetC ; convert one character
or ax,ax ; check for done
jz Done ; end of command line
cmp al,' ' ; a blank space?
jz Loopit ; skip it
; now we must be seeing the beginning of an arguement
inc argc ; count it
add si,4 ; point to next *argv[]
mov [si+2],di ; where string start
mov word ptr [si],0 ; set length to 0
mov dx,' ' ; assume this is the separator
cmp ax,'"' ; start of quoted string?
jne NoQuote ;
mov dx,'"' ; make this the separator
jmp short Next ; don't store the first "
NoQuote:
mov [di],al ; store the character
inc di
inc word ptr [si] ; increment argv's length
Next: call GetC
or ax,ax
jz Done ; end of arguement
cmp ax,dx ; is this the separator?
jz Loopit ; find next arguement
jmp NoQuote ; keep storing
; now done with splitting argv[]'s
Done:
; now let's check for options
mov ah,argc
mov mc,ah ; for mc = argc downto 1 do
mov si,offset argv - 4
or ah,ah ; do we any argv at all?
jz EndOpt
More: add si,4 ; point to *argv[0,1,2,...]
mov bx,[si+2] ; address of string
cmp byte ptr [bx],SWITCH ; is this string an option?
jnz EndOpt ; no more options
; process this option (option can be /abc or /a /b /c or /a/b/c)
mov cx,[si] ; length of option string
Mopts: inc bx ; point to char after the switch
dec cx ; decrement length of option string
jz NextOp ; done with this option string. Next.
; now scrutinize the option letter
mov al,[bx] ; the option letter
cmp al,SWITCH ; is the switch embedded in here?
je Mopts ; ignore it
cmp al,'A' ; check for legal option letters
jb BadOpt
cmp al,'Z'
jbe GoodOpt ; a valid uppercase option letter
cmp al,'a'
jb BadOpt
cmp al,'z'
ja BadOpt
GoodOpt:
mov dl,al ; save option letter in case of error
and al,31 ; convert to 1-26
dec al ; convert to 0-25
xor ah,ah
mov di,ax ; use as an index
mov al,dl ; in case we need this to print error
cmp option[di],1 ; check if this is a known option
je BadOpt ; if not, yell at user
mov option[di],2 ; set the option
jmp short Mopts ; go look at next option char.
BadOpt: ; yell at user for bad option character
mov unkopt,al
mov dx,offset cry
mov ah,9 ; print the error message
int 21h
jmp short Mopts ; look at next option char.
NextOp: dec mc ; count down argc
jnz More
; now process the parameters
EndOpt: cmp mc,0 ; see if there's any arguements at all
ja NoHelp
mov dx,offset helpms ; if not, print a summary
mov ah,9 ; print string
int 21h
xor al,al ; return code 0
jmp Die
NoHelp: ; si is pointing to a parameter *argv[]
mov di,si
add di,4 ; if mc = 2 then di is pointing to the
; expected response string's argv[]
; now see if we should convert the "expected response" to upper case
cmp mc,2 ; is there an "expected response" at all?
jb Ask ; if not, then forget about converting
cmp option + 'c' - 'a',2 ; should we be case sensitive?
je Ask ; i